#ifndef __HEAP_TIMER_H__
#define __HEAP_TIMER_H__

#include <chrono>
#include <functional>
#include <vector>
#include <unordered_map>
#include <assert.h>

using Clock = std::chrono::high_resolution_clock;
using TimerStamp = Clock::time_point;
using MS = std::chrono::milliseconds;
using TimeoutCallBack = std::function<void()>;

struct TimerNode
{
    int id;
    TimerStamp expires;
    TimeoutCallBack cb;
    bool operator<(const TimerNode &t)
    {
        return expires < t.expires;
    }
};

class HeapTimer
{
public:
    HeapTimer() { timerHeap_.reserve(64); }
    ~HeapTimer() {Clear();};
    void Add(int id, int timeOut, const TimeoutCallBack &cb);
    void DoWork(int id);
    void Delete(int index);
    void Adjust(int id, int timeOut);
    void Pop();
    void Clear();
    void Tick();
    int GetNextTick();

private:
    void SiftUp(size_t i);
    bool SiftDown(size_t i, size_t n);
    void SwapNode(size_t i, size_t j);

private:
    std::vector<TimerNode> timerHeap_;
    std::unordered_map<int, size_t> ref_;
};

#endif